using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using FireStarter.Base;
using FireStarter.CodeGeneration;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using FireStarterModeller.UI.CodeGeneration;
using Habanero.Base;
using Habanero.BO;
using Habanero.BO.ClassDefinition;
using Habanero.BO.Loaders;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using Habanero.Util;
using NUnit.Framework;
using DialogResult = Habanero.Faces.Base.DialogResult;
using DockStyle=Habanero.Faces.Base.DockStyle;
using MessageBoxButtons = Habanero.Faces.Base.MessageBoxButtons;
using MessageBoxIcon = Habanero.Faces.Base.MessageBoxIcon;

namespace FireStarterModeller.Test.UI.CodeGeneration
{
    [TestFixture]
    public class TestCodeGenerationForm
    {
        [TestFixtureSetUp]
        public void SetUpFixture()
        {
            GlobalUIRegistry.ControlFactory = new ControlFactoryWinNoPopup();
            ClassDef.ClassDefs.Clear();
            ClassDef.ClassDefs.Add(new XmlClassDefsLoader(BOBroker.GetClassDefsXml(), new DtdLoader()).LoadClassDefs());
            GlobalRegistry.UIExceptionNotifier = new RethrowingExceptionNotifier();
        }

        [SetUp]
        public void Setup()
        {
            BORegistry.DataAccessor = new DataAccessorInMemory();
        }

        private static DMSolution CreateDMSolution()
        {
            DMSolution dmSolution = new DMSolution();
            dmSolution.SolutionName = TestUtilsShared.GetRandomString();
            //GenerationSettings generationSettings = CreateGenerationSettings();
            //dmSolution.GenerationSettings = generationSettings;
            return dmSolution;
        }

        private static GenerationSettings CreateGenerationSettings()
        {
            GenerationSettings generationSettings = new GenerationSettings();
            generationSettings.HabaneroDllPath = TestUtilsShared.GetRandomString();
            generationSettings.SolutionName = TestUtilsShared.GetRandomString();
            generationSettings.SolutionDirectory = TestUtilsShared.GetRandomString();
            return generationSettings;
        }

        private static CodeGenerationForm CreateCodeGenerationForm()
        {
            DMSolution dmSolution = CreateDMSolution();
            return new CodeGenerationForm(dmSolution);
        }

        private static CodeGenerationForm CreateCodeGenerationForm(string solutionName)
        {
            DMSolution dmSolution = new DMSolution();
            dmSolution.SolutionName = solutionName;
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            return codeGenerationForm;
        }

        [Test, Ignore("This is for visual testing")]
        public void Test_Visually_ShowCodeGenForm()
        {
            //---------------Set up test pack-------------------

            DMSolution dmSolution = CreateDMSolution();
            SolutionType solutionType = CreateSolutionType(TestUtilsShared.GetRandomString());
            solutionType.Save();
            dmSolution.GenerationSettings = CreateGenerationSettings();
            CreateDefaultProjectTypes();
            CreateDefaultProjectTypeGenerations(dmSolution);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            codeGenerationForm.ShowDialog();
            //---------------Test Result -----------------------
        }

        [Test, Ignore("This is for visual testing")]
        public void Test_Visually_ShowCodeGenForm_RealisticData()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = new DMSolution("TestSolution"); //TestUtilsDMSolution.CreateSavedDMSolution();
            dmSolution.SolutionName = "TestSolution";
            dmSolution.DefaultAssembly = new DMAssembly("TestSolution.BO"); //TestUtilsDMAssembly.CreateSavedDMAssembly();
            dmSolution.Save();
            DMClass dmClass1 = CreateDMClassWithObjectIdentity(dmSolution, "Class1");
            DMClass dmClass2 = CreateDMClassWithObjectIdentity(dmSolution, "Class2");
            new CodeGenerationController(new GenerationSettings()).GenerateDefaultSolutionTypes();

            dmSolution.GenerationSettings = CreateGenerationSettings();
            dmSolution.GenerationSettings.SolutionName = dmSolution.SolutionName;
            dmSolution.GenerationSettings.SolutionDirectory = @"D:\temp\temp";
            dmSolution.GenerationSettings.HabaneroDllPath = @"D:\systems\habanero\trunk\bin";

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Assert Precondition----------------
            Assert.AreEqual(2, dmSolution.AllClasses.Count);
            Assert.AreEqual(dmClass1.Assembly, dmSolution.DefaultAssembly);
            Assert.AreEqual(dmClass2.Assembly, dmSolution.DefaultAssembly);
            Assert.AreEqual(dmSolution, dmClass1.Assembly.Solution);

            Assert.AreEqual(1, Broker.GetBusinessObjectCollection<DMSolution>("").Count);
            Assert.AreEqual(1, Broker.GetBusinessObjectCollection<DMAssembly>("").Count);
            Assert.AreEqual(2, Broker.GetBusinessObjectCollection<DMClass>("").Count);
            //---------------Execute Test ----------------------
            codeGenerationForm.ShowDialog();
            //---------------Test Result -----------------------
        }

        private static DMClass CreateDMClassWithObjectIdentity(DMSolution dmSolution, string className)
        {
            DMClass dmClass = dmSolution.DefaultAssembly.Classes.CreateBusinessObject();
            dmClass.ClassNameBO = className;
            dmClass.MappedTableName = TestUtilsShared.GetRandomString();
            DMProperty dmProperty = TestUtilsDMProperty.CreateUnsavedValidDMProperty(dmClass);
            dmProperty.HasSetter = true;
            dmProperty.PropertyType = GetOrCreatePropertyType("System", "String");
            dmClass.ObjectIdentity = new DMObjectIdentity();
            dmClass.ObjectIdentity.Properties.Add(dmProperty);
            dmClass.ObjectIdentity.IsObjectID = true;
            UIView uiView = new UIView();
            UIGridInfo uiGridInfo = new UIGridInfo();
            //UIGridColumnInfo uiGridColumnInfo = new UIGridColumnInfo();
            //uiGridColumnInfo.PropertyName = TestUtilsShared.GetRandomString();
            //uiGridInfo.UIColumns.Add(uiGridColumnInfo);
            uiView.UIGridInfo = uiGridInfo;
            UIFormInfo uiFormInfo = new UIFormInfo();
            uiView.UIFormInfo = uiFormInfo;
            dmClass.UIViews.Add(uiView);
            dmClass.Save();
            return dmClass;
        }

        private static DMPropertyType GetOrCreatePropertyType(string assembly, string typeName)
        {
            string criteria = string.Format("PropertyTypeName = '{0}' AND AssemblyName = '{1}'", typeName, assembly);
            DMPropertyType dmPropertyType = Broker.GetBusinessObject<DMPropertyType>(criteria);
            if (dmPropertyType == null)
            {
                dmPropertyType = new DMPropertyType(assembly, typeName);
            }
            return dmPropertyType;
        }

        private static void CreateDefaultProjectTypeGenerations(DMSolution dmSolution)
        {
            BusinessObjectCollection<ProjectType> projectTypes = BORegistry.DataAccessor.BusinessObjectLoader.GetBusinessObjectCollection<ProjectType>("","Name");
            foreach (ProjectType projectType in projectTypes)
            {
                ProjectTypeGeneration projectTypeGeneration = new ProjectTypeGeneration();
                projectTypeGeneration.ProjectName = dmSolution.SolutionName + "." + projectType.Name;
                projectTypeGeneration.GenerationSettings = dmSolution.GenerationSettings;
                projectTypeGeneration.ProjectType = projectType;
                projectTypeGeneration.ToBeGenerated = true;
            }
        }

        [Test]
        public void Test_Construct()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof(FormWin), codeGenerationForm);
            Assert.AreEqual("Generate Code", codeGenerationForm.Text);
            Assert.IsTrue(codeGenerationForm.ControlBox);
            Assert.IsFalse(codeGenerationForm.MaximizeBox);
            Assert.IsFalse(codeGenerationForm.MinimizeBox);
            Assert.AreEqual(600, codeGenerationForm.Width);
            Assert.AreEqual(600, codeGenerationForm.Height);
            Assert.AreEqual(400, codeGenerationForm.MinimumSize.Width);
            Assert.AreEqual(400, codeGenerationForm.MinimumSize.Height);
            Assert.AreEqual(10, codeGenerationForm.Padding.All);
            Assert.AreSame(dmSolution, codeGenerationForm.DMSolution);
        }

        [Test]
        public void Test_Construct_ShouldCreateDefaultGenerationSettings()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmSolution.GenerationSettings);
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dmSolution.GenerationSettings);
            Assert.IsNotNull(dmSolution.GenerationSettings.CodeGenerationController);
        }

        [Test]
        public void Test_Construct_WithExistingGenerationSettings_ShouldEnsureThatCodeGenerationControllerIsSet()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            dmSolution.GenerationSettings = new GenerationSettings();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution.GenerationSettings);
            Assert.IsNull(dmSolution.GenerationSettings.CodeGenerationController);
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNotNull(dmSolution.GenerationSettings);
            Assert.IsNotNull(dmSolution.GenerationSettings.CodeGenerationController);
        }

        [Test]
        public void Test_Construct_WithNullDMSolution_ShouldThrowException()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            try
            {
                new CodeGenerationForm(null);
                Assert.Fail("Should throw exception if DMSolution is null.");
            }
            //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
            }
        }

        [Test]
        public void Test_Construct_WithExistingGenerationSettings()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            GenerationSettings generationSettings = CreateGenerationSettings();
            dmSolution.GenerationSettings = generationSettings;
            SolutionType solutionType = CreateSolutionType(TestUtilsShared.GetRandomString());
            solutionType.Save();
            CreateSolutionTypeProject(solutionType, CreateProjectType(TestUtilsShared.GetRandomString())).Save();
            CreateSolutionTypeProject(solutionType, CreateProjectType(TestUtilsShared.GetRandomString())).Save();
            CreateSolutionTypeProject(solutionType, CreateProjectType(TestUtilsShared.GetRandomString())).Save();
            generationSettings.SolutionType = solutionType;
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreSame(dmSolution, codeGenerationForm.DMSolution);
            Assert.AreEqual(2, codeGenerationForm.SolutionTypeComboBox.Items.Count);
        }

        [Test]
        public void Test_BasicLayout()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(3, codeGenerationForm.Controls.Count);
            Assert.IsInstanceOf(typeof (IGroupBox), codeGenerationForm.Controls[0]);
            Assert.IsInstanceOf(typeof (IGroupBox), codeGenerationForm.Controls[1]);
            Assert.IsInstanceOf(typeof (IButtonGroupControl), codeGenerationForm.Controls[2]);

            Assert.AreSame(codeGenerationForm.ProjectsGroupBox, codeGenerationForm.Controls[0]);
            Assert.AreSame(codeGenerationForm.GenerationSettingsGroupBox, codeGenerationForm.Controls[1]);
            Assert.AreSame(codeGenerationForm.Buttons, codeGenerationForm.Controls[2]);
        }

        [Test]
        public void Test_Buttons()
        {
            //---------------Set up test pack-------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            IButtonGroupControl buttons = codeGenerationForm.Buttons;
            //---------------Test Result -----------------------
            Assert.AreEqual(2, buttons.Controls.Count);
            Assert.IsInstanceOf(typeof (IButton), buttons.Controls[0]);
            Assert.IsInstanceOf(typeof (IButton), buttons.Controls[1]);
            Assert.AreSame(codeGenerationForm.CloseButton, buttons.Controls[0]);
            Assert.AreSame(codeGenerationForm.GenerateButton, buttons.Controls[1]);
            Assert.AreEqual("Generate", codeGenerationForm.GenerateButton.Text);
            Assert.AreEqual("Close", codeGenerationForm.CloseButton.Text);
            Assert.AreEqual(codeGenerationForm.CloseButton, codeGenerationForm.CancelButton);
        }

        [Test]
        public void Test_CloseButton_WhenClicked_ShouldCloseForm()
        {
            //---------------Set up test pack-------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            bool close = false;
            codeGenerationForm.Closing += delegate { close = true; };
            codeGenerationForm.Show();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            codeGenerationForm.CloseButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.IsTrue(close);
        }

        [Test]
        public void Test_GenerationSettingsGroupBox_SolutionName()
        {
            //---------------Set up test pack-------------------
            string solutionName = TestUtilsShared.GetRandomString();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm(solutionName);
            //---------------Test Result -----------------------
            IGroupBox settingsGroupBox = codeGenerationForm.GenerationSettingsGroupBox;
            IPanelInfo settingsPanelInfo = codeGenerationForm.GenerationSettingsPanelInfo;
            Assert.AreEqual(1, settingsGroupBox.Controls.Count);
            IControlHabanero control = settingsGroupBox.Controls[0];
            Assert.IsInstanceOf(typeof(IPanel), control);
            Assert.AreEqual(DockStyle.Fill, control.Dock);
            Assert.AreNotEqual(0, control.Controls.Count);
            int expectedHeight = settingsPanelInfo.MinimumPanelHeight + 20;
            Assert.AreEqual(expectedHeight, settingsGroupBox.Height);
        }

        [Test]
        public void Test_ProjectsGroupBox_BasicLayout()
        {
            //---------------Set up test pack-------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            IGroupBox projectsGroupBox = codeGenerationForm.ProjectsGroupBox;
            //---------------Test Result -----------------------
            Assert.AreEqual(2, projectsGroupBox.Controls.Count);
            Assert.IsInstanceOf(typeof(IButton), codeGenerationForm.AutoNamingButton);
            Assert.IsInstanceOf(typeof(IEditableGridControl), codeGenerationForm.ProjectTypeGenerationGridControl);
            IEditableGridControl projectTypeGenerationGridControl = codeGenerationForm.ProjectTypeGenerationGridControl;

            IButton autoNamingButton = codeGenerationForm.AutoNamingButton;
            Assert.Greater(projectsGroupBox.Width, autoNamingButton.Width);
            Assert.Greater(autoNamingButton.Width, 200);
            Assert.AreEqual("Auto Create Project Naming", autoNamingButton.Text);
            
            Assert.IsFalse(projectTypeGenerationGridControl.AllowUsersToAddBO);
            Assert.IsFalse(projectTypeGenerationGridControl.AllowUsersToDeleteBO);

            Assert.AreSame(ClassDef.Get<ProjectTypeGeneration>(), projectTypeGenerationGridControl.ClassDef);
        }

        [Test]
        public void Test_Solution_ShouldPopulateGenerationSettings()
        {
            //---------------Set up test pack-------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            DMSolution solution = codeGenerationForm.DMSolution;
            IPanelInfo generationSettingsPanelInfo = codeGenerationForm.GenerationSettingsPanelInfo;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(solution.GenerationSettings);
            //---------------Execute Test ----------------------
            IBusinessObject businessObject = generationSettingsPanelInfo.BusinessObject;
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof(IButton), codeGenerationForm.AutoNamingButton);
            IButton autoNamingButton = codeGenerationForm.AutoNamingButton;
            //Assert.AreEqual(558, autoNamingButton.Width, "Should be 200, will fix layout manager.");
            Assert.AreEqual("Auto Create Project Naming", autoNamingButton.Text);
        }

        [Test]
        public void Test_ShouldPopulateProjectTypeGenerationGridControl()
        {
            //---------------Set up test pack-------------------
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            //---------------Test Result -----------------------
            DMSolution solution = codeGenerationForm.DMSolution;
            Assert.IsNotNull(solution.GenerationSettings);
            Assert.AreSame(solution.GenerationSettings.ProjectTypeGenerations, codeGenerationForm.ProjectTypeGenerationGridControl.BusinessObjectCollection);
        }

        [Test]
        public void Test_IfGenerationSettingsHasTheSameProjectTypeGenerations()
        {
            //---------------Set up test pack-------------------
            CodeGenerationForm codeGenerationForm = CreateCodeGenerationForm();
            DMSolution solution = codeGenerationForm.DMSolution;
            BusinessObjectCollection<ProjectTypeGeneration> generations = solution.GenerationSettings.ProjectTypeGenerations;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(generations);
            Assert.AreEqual(0,generations.Count);
            //---------------Execute Test ----------------------
            solution.GenerationSettings.ProjectTypeGenerations.CreateBusinessObject();
            solution.GenerationSettings.ProjectTypeGenerations.CreateBusinessObject();
            solution.GenerationSettings.ProjectTypeGenerations.CreateBusinessObject();
            //---------------Test Result -----------------------
            Assert.AreEqual(3,generations.Count);
            Assert.AreEqual(3,codeGenerationForm.ProjectTypeGenerationGridControl.BusinessObjectCollection.Count);
        }


        [Test]
        public void Test_CreateSolutionGenerationSettingsProjetTypeSolutionType()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            dmSolution.GenerationSettings = CreateGenerationSettings();
            GenerationSettings generationSettings = dmSolution.GenerationSettings;
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            ProjectType projectType = CreateProjectType(TestUtilsShared.GetRandomString());
            SolutionType solutionType = CreateSolutionType(TestUtilsShared.GetRandomString());
            SolutionTypeProject solutionTypeProject = CreateSolutionTypeProject(solutionType, projectType);
            ProjectTypeGeneration projectTypeGeneration = CreateProjectTypeGeneration(projectType, generationSettings);
            //---------------Test Result -----------------------
            Assert.AreEqual(1,generationSettings.ProjectTypeGenerations.Count);
            Assert.AreSame(solutionType,solutionTypeProject.SolutionType);
            Assert.AreSame(projectType,projectTypeGeneration.ProjectType);
        }

        //[Test]
        //public void Test_PopulateGenerationSettings_WhenNotAvailable()
        //{
        //    //---------------Set up test pack-------------------
        //    DMSolution dmSolution = new DMSolution();
            
        //    //---------------Assert Precondition----------------
        //    Assert.IsNull(dmSolution.GenerationSettings);
        //    //---------------Execute Test ----------------------
        //    CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
        //    //---------------Test Result -----------------------
        //    GenerationSettings generationSettings = dmSolution.GenerationSettings;
        //    Assert.IsNotNull(generationSettings);
        //    //Assert.AreEqual(3, generationSettings.ProjectTypeGenerations.Count);
        //    BusinessObjectCollection<SolutionType> solutionTypes = Broker.GetBusinessObjectCollection<SolutionType>("", "Name");
        //    //List<string> solutionTypes = new List<string>();
        //    //foreach (ProjectTypeGeneration projectTypeGeneration in generationSettings.ProjectTypeGenerations)
        //    //{
        //    //    solutionTypes.Add(projectTypeGeneration.ProjectType.Name);
        //    //}
        //    Assert.AreEqual(3, solutionTypes.Count);
        //    Assert.AreEqual("Windows (Win Forms)", solutionTypes[2].Name);
        //    Assert.AreEqual("Web (Visual WebGui)", solutionTypes[1].Name);
        //    Assert.AreEqual("Dual Windows/Web (Win Forms/Visual WebGui)", solutionTypes[0].Name);
        //}

        [Test]
        public void Test_Solution_ShouldSetProjectName()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            Assert.IsNotNull(dmSolution.SolutionName);
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual(dmSolution.SolutionName, dmSolution.GenerationSettings.SolutionName);
        }

        [Test]
        public void Test_SolutionDirectory_Source_IfAbsoluteRootExists()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            dmSolution.SolutionDirectory = Assembly.GetExecutingAssembly().Location;
            //---------------Assert Precondition----------------
            Assert.IsTrue(Path.IsPathRooted(dmSolution.SolutionDirectory));
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.AreEqual("source", dmSolution.GenerationSettings.SolutionDirectory);
        }

        [Test]
        public void Test_SolutionDirectory_Empty_IfAbsoluteRootDoesNotExist()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            Assert.IsNull(dmSolution.SolutionDirectory);
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNull(dmSolution.GenerationSettings.SolutionDirectory);
        }

        [Test, Ignore("Button click not being picked up")]
        public void Test_AutoNamingButton_ShouldAutoGenerateNames()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            string originalSolutionName = dmSolution.SolutionName;

            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            codeGenerationForm.SolutionTypeComboBox.SelectedIndex = 1;

            ProjectTypeGeneration firstProjectTypeGen =
                dmSolution.GenerationSettings.ProjectTypeGenerations[0];
            //---------------Assert Precondition----------------
            StringAssert.Contains(originalSolutionName, firstProjectTypeGen.ProjectName);
            //---------------Execute Test ----------------------
            string customSolutionName = TestUtilsShared.GetRandomString();
            dmSolution.GenerationSettings.SolutionName = customSolutionName;
            codeGenerationForm.AutoNamingButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.AreNotEqual(originalSolutionName, customSolutionName);
            StringAssert.Contains(customSolutionName, firstProjectTypeGen.ProjectName);
        }

        [Test]
        public void Test_Test_AutoNamingButton_NoEffectWhenSolutionTypeNull()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Assert Precondition----------------
            Assert.AreEqual(0, codeGenerationForm.ProjectTypes.Count);
            //---------------Execute Test ----------------------
            codeGenerationForm.AutoNamingButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.AreEqual(0, codeGenerationForm.ProjectTypes.Count);
        }

        [Test]
        public void Test_SelectingTestProject_ShowsAlphaWarning()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);

            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            BusinessObjectCollection<ProjectTypeGeneration> projectTypeGenerations = codeGenerationForm.ProjectTypes;
            foreach (ProjectTypeGeneration projectTypeGeneration in projectTypeGenerations)
            {
                if (projectTypeGeneration.ProjectType.Name.ToUpper().Contains("TEST.BO"))
                {
                    projectTypeGeneration.ToBeGenerated = true;
                    break;
                }
            }
            //---------------Test Result -----------------------
            // Must show the message box, which can't be tested here
        }

        [Test]
        public void Test_CheckBoxColumnIsReadOnly()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            IEditableGrid editableGrid = codeGenerationForm.ProjectTypeGenerationGridControl.Grid;
            foreach (IDataGridViewColumn column in editableGrid.Columns)
            {
                if (column.Control is DataGridViewCheckBoxColumn)
                {
                    Assert.IsTrue(((DataGridViewCheckBoxColumn)column.Control).ReadOnly);
                }
            }
        }

        [Test]
        public void Test_CheckBoxColumnTurnsClickEventIntoValueChange()
        {
            // Just for the record (this can't be tested):
            // When you click on checkbox cell (ToBeGenerated), it must change the value underneath.
            // See: http://www.chillisoft.co.za/blog/?p=46
        }

        [Test]
        public void Test_GenerateButton_GeneratesCode()
        {
            //---------------Set up test pack-------------------
            GeneratorStub generator = new GeneratorStub();
            DMSolution dmSolution = TestUtilsDMSolution.CreateSavedDMSolution(); //CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            codeGenerationForm.Generator = generator;
            codeGenerationForm.Show();
            //---------------Assert Precondition----------------
            Assert.IsFalse(generator.HasDoneSetup);
            Assert.IsFalse(generator.HasGenerated);
            //---------------Execute Test ----------------------
            codeGenerationForm.GenerateButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.IsTrue(generator.HasDoneSetup);
            Assert.IsTrue(generator.HasGenerated);
            //---------------Tear Down--------------------------
            codeGenerationForm.Close();
        }

        [Test]
        public void Test_GenerateButton_CopiesClassDefsXmlToGenerator()
        {
            //---------------Set up test pack-------------------
            GeneratorStub generator = new GeneratorStub();
            DMSolution dmSolution = TestUtilsDMSolution.CreateSavedDMSolution();// CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            codeGenerationForm.Generator = generator;
            codeGenerationForm.Show();
            //---------------Assert Precondition----------------
            Assert.IsNull(generator.ClassDefsXml);
            //---------------Execute Test ----------------------
            codeGenerationForm.GenerateButton.PerformClick();
            //---------------Test Result -----------------------
            Assert.IsNotNull(generator.ClassDefsXml);
            //---------------Tear Down--------------------------
            codeGenerationForm.Close();
        }

        [Test]
        public void Test_GeneratorProperty_DefaultsToMasterGenerator()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNotNull(codeGenerationForm.Generator);
            Assert.IsInstanceOf(typeof(MasterGenerator), codeGenerationForm.Generator);
        }

        [Test]
        public void Test_SolutionDirectoryControl_ShouldBeFileSelectorControl()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNotNull(codeGenerationForm.SolutionDirectoryControl);
            Assert.IsInstanceOf(typeof(DirectorySelectorControl), codeGenerationForm.SolutionDirectoryControl);
        }

        [Test]
        public void Test_HabaneroDllPathControl_ShouldBeFileSelectorControl()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            Assert.IsNotNull(codeGenerationForm.HabaneroDllPathControl);
            Assert.IsInstanceOf(typeof(DirectorySelectorControl), codeGenerationForm.HabaneroDllPathControl);
        }



        //----------------------------------------------------------------------------------------

        private void CreateDefaultProjectTypes()
        {
            CreateProjectType(GenerationTypes.PROJECT_TYPE_BO);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_LOGIC);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_MAIN_VWG);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_MAIN_WIN);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_TEST_BASE);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_TEST_BO);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_TEST_LOGIC);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_TEST_UI);
            //CreateProjectType(GenerationTypes.PROJECT_TYPE_UI);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_UI_BASE);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_UI_VWG);
            CreateProjectType(GenerationTypes.PROJECT_TYPE_UI_WIN);
        }


        private ProjectType CreateProjectType(string typeName)
        {
            ProjectType projectType = new ProjectType();
            projectType.Name = typeName;
            projectType.Save();
            return projectType;
        }

        private SolutionType CreateSolutionType(string solutionTypeName)
        {
            SolutionType solutionType = new SolutionType();
            solutionType.Name = solutionTypeName;
            return solutionType;
        }

        private SolutionTypeProject CreateSolutionTypeProject(SolutionType solutionType,ProjectType projectType)
        {
            SolutionTypeProject solutionTypeProject = new SolutionTypeProject();
            solutionTypeProject.SolutionType = solutionType;
            solutionTypeProject.ProjectType = projectType;
            return solutionTypeProject;
        }

        private ProjectTypeGeneration CreateProjectTypeGeneration(ProjectType projectType,GenerationSettings generationSettings)
        {
            ProjectTypeGeneration projectTypeGeneration = new ProjectTypeGeneration();
            projectTypeGeneration.ProjectType = projectType;
            projectTypeGeneration.ProjectName = TestUtilsShared.GetRandomString();
            projectTypeGeneration.GenerationSettings = generationSettings;
            return projectTypeGeneration;
        }

        public static DMSolution CreateSavedDMSolutionWithClass()
        {
            DMSolution solution = CreateDMSolution();
            solution.DefaultAssembly = TestUtilsDMAssembly.CreateSavedDMAssembly();
            TestUtilsDMClass.CreateSavedDMClass(solution);
            TestUtilsDMClass.CreateSavedDMClass(solution);
            return solution;
        }

        private class GeneratorStub : IMasterGenerator
        {
            public bool HasGenerated { get; private set; }
            public bool HasDoneSetup { get; private set; }
            public string ClassDefsXml { get; set; }

            public Result Generate()
            {
                HasGenerated = true;
                return new Result(true);
            }

            public void SetupGenerator(DMSolution dmSolution)
            {
                HasDoneSetup = true;
            }
        }

        [Test]
        public void Test_SolutionTypeComboBox_ShouldHaveAllSolutionTypesAndBlank()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            //---------------Assert Precondition----------------
            //---------------Execute Test ----------------------
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Test Result -----------------------
            IComboBox solutionTypeComboBox = codeGenerationForm.SolutionTypeComboBox;
            Assert.IsNotNull(solutionTypeComboBox);
            int numSolutionTypes = Broker.GetBusinessObjectCollection<SolutionType>("").Count;
            Assert.AreEqual(numSolutionTypes + 1, solutionTypeComboBox.Items.Count);
            Assert.AreEqual(-1, solutionTypeComboBox.SelectedIndex);
        }

        [Test]
        public void Test_SolutionTypeComboBox_WhenChanged_TestProjectsNotTickedByDefault()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            codeGenerationForm.SolutionTypeComboBox.SelectedIndex = 1;
            //---------------Test Result -----------------------
            BusinessObjectCollection<ProjectTypeGeneration> projectTypeGenerations = codeGenerationForm.ProjectTypes;
            foreach (ProjectTypeGeneration projectTypeGeneration in projectTypeGenerations)
            {
                if (projectTypeGeneration.ProjectType.Name.ToUpper().Contains("TEST"))
                {
                    Assert.IsFalse(projectTypeGeneration.ToBeGenerated.Value);
                }
            }
        }

        [Test]
        public void Test_SolutionTypeComboBox_WhenChanged_PopulatesProjectNames()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            string originalSolutionName = dmSolution.SolutionName;

            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            string customSolutionName = TestUtilsShared.GetRandomString();
            dmSolution.GenerationSettings.SolutionName = customSolutionName;
            //---------------Assert Precondition----------------
            Assert.AreNotEqual(originalSolutionName, customSolutionName);
            Assert.AreEqual(0, dmSolution.GenerationSettings.ProjectTypeGenerations.Count);
            //---------------Execute Test ----------------------
            codeGenerationForm.SolutionTypeComboBox.SelectedIndex = 1;
            //---------------Test Result -----------------------
            ProjectTypeGeneration firstProjectTypeGen =
                dmSolution.GenerationSettings.ProjectTypeGenerations[0];
            StringAssert.Contains(customSolutionName, firstProjectTypeGen.ProjectName);
        }

        [Test]
        public void Test_SolutionTypeComboBox_WhenChanged_PopulatesProjectTypes()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            IComboBox solutionTypeComboBox = codeGenerationForm.SolutionTypeComboBox;
            //---------------Assert Precondition----------------
            Assert.IsNotNull(solutionTypeComboBox);
            int numSolutionTypes = Broker.GetBusinessObjectCollection<SolutionType>("").Count;
            Assert.AreEqual(numSolutionTypes + 1, solutionTypeComboBox.Items.Count);
            Assert.AreEqual(-1, solutionTypeComboBox.SelectedIndex);
            Assert.AreEqual(0, codeGenerationForm.ProjectTypes.Count);
            Assert.AreEqual(0, dmSolution.GenerationSettings.ProjectTypeGenerations.Count);
            //---------------Execute Test ----------------------
            solutionTypeComboBox.SelectedIndex = 1;
            //---------------Test Result -----------------------
            SolutionType solutionType = dmSolution.GenerationSettings.SolutionType;
            Assert.IsNotNull(solutionType, "Changing index should have changed BO");
            List<string> linkedProjects = SolutionType.GetLinkedProjects(solutionType).ConvertAll(input => input.Name);
            Assert.AreEqual(linkedProjects.Count, codeGenerationForm.ProjectTypes.Count);
            Assert.AreEqual(linkedProjects.Count, codeGenerationForm.ProjectTypeGenerationGridControl.Grid.Rows.Count);
        }

        [Test]
        public void Test_SolutionTypeComboBox_WhenChanged_SecondChangeClearsAndRepopulatesProjectTypes()
        {
            //---------------Set up test pack-------------------
            DMSolution dmSolution = CreateDMSolution();
            CodeGenerationForm codeGenerationForm = new CodeGenerationForm(dmSolution);
            IComboBox solutionTypeComboBox = codeGenerationForm.SolutionTypeComboBox;
            solutionTypeComboBox.SelectedIndex = 1;

            //---------------Assert Precondition----------------
            SolutionType solutionType1 = dmSolution.GenerationSettings.SolutionType;
            List<string> linkedProjects1 = SolutionType.GetLinkedProjects(solutionType1).ConvertAll(input => input.Name);
            Assert.AreEqual(linkedProjects1.Count, codeGenerationForm.ProjectTypes.Count);
            //---------------Execute Test ----------------------
            solutionTypeComboBox.SelectedIndex = 2;
            //---------------Test Result -----------------------
            SolutionType solutionType2 = dmSolution.GenerationSettings.SolutionType;
            Assert.AreNotEqual(solutionType2, solutionType1, "Changing ComboBox should give a different SolutionType.");
            List<string> linkedProjects2 = SolutionType.GetLinkedProjects(solutionType2).ConvertAll(input => input.Name);
            Assert.AreEqual(linkedProjects2.Count, codeGenerationForm.ProjectTypes.Count);
            Assert.AreEqual(linkedProjects2.Count, codeGenerationForm.ProjectTypeGenerationGridControl.Grid.Rows.Count);
        }

        [Test]
        public void Test_CleanUpSolution_ShouldSetAllClassesClonedClassesToNull()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            IList<IModelProperty> properties = ((IModelClass) dmClass).AllProperties;
            CodeGenerationForm form = new CodeGenerationForm(new DMSolution());
            //---------------Assert Precondition----------------
            object clonedClass = ReflectionUtilities.GetPrivatePropertyValue(dmClass, "ClonedClass");
            Assert.IsNotNull(clonedClass);
            //---------------Execute Test ----------------------
            ReflectionUtilities.ExecutePrivateMethod(form, "CleanUpSolution");
            //---------------Test Result -----------------------
            object clonedClassAfterClear = ReflectionUtilities.GetPrivatePropertyValue(dmClass, "ClonedClass");
            Assert.IsNull(clonedClassAfterClear);
        }

#pragma warning disable 168
        [Test]
        public void Test_GenerateButtonClicked_ShouldSetAllClassesClonedClassesToNull()
        {
            //---------------Set up test pack-------------------
            DMClass dmClass = TestUtilsDMClass.CreateSavedDMClass();
            IList<IModelProperty> properties = ((IModelClass) dmClass).AllProperties;
            CodeGenerationForm form = new CodeGenerationForm(TestUtilsDMSolution.CreateSavedDMSolution());
            form.Generator = new GeneratorStub();
            //---------------Assert Precondition----------------
            object clonedClass = ReflectionUtilities.GetPrivatePropertyValue(dmClass, "ClonedClass");
            Assert.IsNotNull(clonedClass);
            //---------------Execute Test ----------------------
            ReflectionUtilities.ExecutePrivateMethod(form, "Generate");
            //---------------Test Result -----------------------
            object clonedClassAfterClear = ReflectionUtilities.GetPrivatePropertyValue(dmClass, "ClonedClass");
            Assert.IsNull(clonedClassAfterClear);
        }
#pragma warning restore 168
    }

    public class ControlFactoryWinNoPopup : ControlFactoryWin
    {
        public override DialogResult ShowMessageBox(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon)
        {
            return DialogResult.None;
        }

        public override DialogResult ShowMessageBox(string message, string title, MessageBoxButtons buttons, MessageBoxIcon icon, DialogCompletionDelegate dialogCompletionDelegate)
        {
            return DialogResult.None;
        }

        public override DialogResult ShowMessageBox(string message)
        {
            return DialogResult.None;
        }
    }
}
